#include "statsxx/machine_learning/activation_functions/Logistic.hpp"

// STL
#include <algorithm> // std::max()
#include <cmath>     // std::exp(), std::log()


inline activation_function::Logistic::Logistic() {};

inline activation_function::Logistic::~Logistic() {};


//
//     f(x) = 1/(1 + exp(-x))
//
inline double activation_function::Logistic::f(const double x)
{
    return ( 1./(1. + std::exp(-x)) );
}

//
//     f'(x) = f(x)*(1 - f(x))
//
inline double activation_function::Logistic::df(const double x)
{
    double fx = this->f(x);

    return ( fx*(1. - fx) );
}

//
//     f(x) = 1/(1 + exp(-x))
//     1 + exp(-x) = 1/f(x)
//     exp(-x) = 1/f(x) - 1
//     x = -log( 1/f(x) - 1 )
//     inserting f(x) returns then x = x??
//
inline double activation_function::Logistic::inv(const double fx)
{
    // NOTE: this is used to prevent trying to take the logarithm of 0
    static const double small = 1.e-16;

    //=========================================================

    double r = 1./fx - 1.;

    r = std::max(r, small);

    return -std::log(r);
}
